//
//  KeepLiveService.m
//  VidoarDemo
//
//  Created by xm on 2025/6/18.
//

#import "KeepLiveService.h"
#import <CoreLocation/CoreLocation.h>
#import <AVFoundation/AVFoundation.h>



@interface KeepLiveService()<CLLocationManagerDelegate, AVAudioPlayerDelegate>

@property(nonatomic, strong) XMLogger *logger;
@property(nonatomic, strong) NSMutableDictionary *taskLog;
@property(nonatomic, strong) NSMutableDictionary *audioLog;
@property(nonatomic, strong) NSMutableDictionary *locationLog;
@property(nonatomic, assign) NSTimeInterval startTimestamp;
@property (nonatomic,strong) NSTimer *Timer;
@property(nonatomic, assign) NSInteger times;
@property (nonatomic, assign) UIBackgroundTaskIdentifier taskMode_backgrounTaskID;
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;
@property (nonatomic, assign) BOOL isPlaying;



@end

@implementation KeepLiveService

static NSString* audioFileName = @"bluetoothvoice_5.mp3";

#pragma mark - getter
- (XMLogger *)logger
{
    if(!_logger){
        _logger = [XMLogger loggerWithScopeName:NSStringFromClass(self.class)];
    }
    
    return _logger;
}


+ (instancetype)share{
    static KeepLiveService *bus = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        bus = [[KeepLiveService alloc]init];
        bus.logger.log(@"share status:%ld", bus.status);
    });
    
    
        
    return bus;
}

- (NSMutableDictionary *)taskLog
{
    if(_taskLog == nil){
        _taskLog = [NSMutableDictionary dictionary];
        [_taskLog setObject:@(KeepLiveService_Mode_Task) forKey:@"mode"];
        [_taskLog setObject:@(0) forKey:@"duration"];
        [_taskLog setObject:@(0) forKey:@"lastDuration"];
    }
    
    return _taskLog;
}

- (NSMutableDictionary *)audioLog
{
    if(_audioLog == nil){
        _audioLog = [NSMutableDictionary dictionary];
        [_audioLog setObject:@(KeepLiveService_Mode_Audio) forKey:@"mode"];
        [_audioLog setObject:@(0) forKey:@"duration"];
        [_audioLog setObject:@(0) forKey:@"lastDuration"];
    }
    
    return _audioLog;
}

- (NSMutableDictionary *)locationLog
{
    if(_locationLog == nil){
        _locationLog = [NSMutableDictionary dictionary];
        [_locationLog setObject:@(KeepLiveService_Mode_Location) forKey:@"mode"];
        [_locationLog setObject:@(0) forKey:@"duration"];
        [_locationLog setObject:@(0) forKey:@"lastDuration"];
    }
    
    return _locationLog;
}

- (CLLocationManager *)locationManager
{
    if(_locationManager == nil){
        _locationManager = [[CLLocationManager alloc] init];
    }
    
    _locationManager.delegate = self;
    _locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers; // 低精度减少耗电
    [_locationManager requestAlwaysAuthorization];
    
    return _locationManager;
}
- (AVAudioPlayer *)audioPlayer
{
    if(_audioPlayer ==nil){
        NSError *error;
        NSURL *audioURL = [NSURL fileURLWithPath:audioFileName];

        _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
        _audioPlayer.numberOfLoops = -1; // 无限循环
        _audioPlayer.volume = 0.1;     // 极小音量，几乎听不到
        _audioPlayer.delegate =self;
    }
    
    return _audioPlayer;
}

-(void) run
{
    self.logger.log(@"run");

    
    
    
    
    NSDictionary* planLog = m3_userDefaults.planLog;
    
    self.logger.log(@"run planLog:%@", [planLog mj_JSONString]);
    self.logger.log(@"run location log:%@", [planLog objectForKey:@"location"] );
    
    if([planLog objectForKey:@"task"] != nil){
        NSDictionary* log = [planLog objectForKey:@"task"];
        self.taskLog[@"lastDuration"] = log[@"duration"];
        self.lastDuration = ((NSNumber*) log[@"duration"]).intValue;
        
    }
    if([planLog objectForKey:@"audio"] != nil){
        NSDictionary* log = [planLog objectForKey:@"audio"];
        self.audioLog[@"lastDuration"] = log[@"duration"];
        self.lastDuration = ((NSNumber*) log[@"duration"]).intValue;
        
    }
    if([planLog objectForKey:@"location"]  != nil){
        NSDictionary* log = [planLog objectForKey:@"location"];
        self.logger.log(@"log %@",[log mj_JSONString]);
        
        self.locationLog[@"lastDuration"] = log[@"duration"];
        self.lastDuration = ((NSNumber*) log[@"duration"]).intValue;
        
    }
    
    self.mode = m3_userDefaults.keepLiveMode;
 
    
    [self watch];
    
    
    
    self.logger.log(@"run mode:%ld", self.mode);
    self.logger.log(@"run status:%ld", self.status);
    self.logger.log(@"run lastDuration:%ld", self.lastDuration);
    self.logger.log(@"run taskLog:%@", [self.taskLog mj_JSONString]);
    self.logger.log(@"run audioLog:%@", [self.audioLog mj_JSONString]);
    self.logger.log(@"run locationLog:%@", [self.locationLog mj_JSONString]);
    
    
}

-(void) switchMode:(KeepLiveService_Mode)mode
{
    self.logger.log(@"switchMode mode:%ld status:%ld", mode, self.status);
    if(mode != self.mode && self.status == KeepLiveService_Status_doing){
        [self stop];
    }
    self.mode = mode;
}

-(void) start
{
    
    self.logger.log(@"start status:%ld mode:%ld", self.status, self.mode);
    if(self.status == KeepLiveService_Status_doing){
        return;
    }
    
 
    self.startTimestamp = [[NSDate date] timeIntervalSince1970];

    
    self.status = KeepLiveService_Status_doing;
    
    if(self.mode == KeepLiveService_Mode_Task){
        [self taskMode_start];
       
    }else   if(self.mode == KeepLiveService_Mode_Audio){
        [self audioMode_start];
        
    }else   if(self.mode == KeepLiveService_Mode_Location){
        [self locationMode_start];
        
    }
    
}

- (void)stop {
    self.logger.log(@"stop");
    
    if(self.mode == KeepLiveService_Mode_Task){
        [self taskMode_stop];
    }else   if(self.mode == KeepLiveService_Mode_Audio){
        [self audioMode_stop];
    }else   if(self.mode == KeepLiveService_Mode_Location){
        [self locationMode_stop];
    }
    self.status = KeepLiveService_Status_none;
}

- (void)watch {
    @weakify(self);
    [m3_global.subject subscribeCode:GlobalBusSubjectCode_App_EnterBackground caller:self block:^(id  _Nullable payload) {
        @strongify(self);
        if(self == nil){
            return;
        }
        
        [self start];
        
    }];
    
    [RACObserve(self, mode) subscribeNext:^(id  _Nullable x) {
        if(self.mode != m3_userDefaults.keepLiveMode){
            m3_userDefaults.keepLiveMode = self.mode;
            
        }
        
        NSNumber* lastDuration = @(0);
        if(self.mode == KeepLiveService_Mode_Task){
            lastDuration = self.taskLog[@"lastDuration"];
           
        }else if(self.mode == KeepLiveService_Mode_Audio){
            lastDuration = self.audioLog[@"lastDuration"];
           
        }else if(self.mode == KeepLiveService_Mode_Location){
            lastDuration = self.locationLog[@"lastDuration"];

           
        }
        
        
        self.lastDuration = lastDuration.intValue;
        self.duration = 0;
        
        self.logger.log(@"mode mode:%ld", self.mode);
        self.logger.log(@"mode taskLog:%@", [self.taskLog mj_JSONString]);
        self.logger.log(@"mode audioLog:%@", [self.audioLog mj_JSONString]);
        self.logger.log(@"mode locationLog:%@", [self.locationLog mj_JSONString]);
        self.logger.log(@"mode lastDuration:%ld", lastDuration.intValue);
        
        
        if(self.mode == KeepLiveService_Mode_Location){
            [self locationMode_requestAuthorizaton];
           
        }
    }];
    
    [RACObserve(self, duration) subscribeNext:^(id  _Nullable x) {
        if(self.duration == 0){
            return;
        }
            
        if(self.duration % 2 == 0){
   
            if(self.mode == KeepLiveService_Mode_Task){
                self.taskLog[@"duration"] = @(self.duration);
            }else if(self.mode == KeepLiveService_Mode_Audio){
                self.audioLog[@"duration"] = @(self.duration);
               
            }else if(self.mode == KeepLiveService_Mode_Location){
                self.locationLog[@"duration"] = @(self.duration);
               
            }
            
            m3_userDefaults.planLog = @{
                @"task": self.taskLog,
                @"audio": self.audioLog,
                @"location": self.locationLog,
            };
            
            self.logger.log(@"locationLog:%@", [self.locationLog mj_JSONString]);
            
        }
    
        
    }];
    
//    [m3_global.subject subscribeCode:GlobalBusSubjectCode_App_EnterForeground caller:self block:^(id  _Nullable payload) {
//        @strongify(self);
//        if(self == nil){
//            return;
//        }
//        
//        [self stop];
//    }];
    
    [RACObserve(self, mode) subscribeNext:^(id  _Nullable x) {
        m3_userDefaults.keepLiveMode = self.mode;
        
        NSNumber* last;
        if(self.mode == KeepLiveService_Mode_Task){
            last =  self.taskLog[@"lastDuration"];
            
        }else if(self.mode == KeepLiveService_Mode_Audio){
            last =  self.audioLog[@"lastDuration"];
           
        }else if(self.mode == KeepLiveService_Mode_Location){
            last =  self.locationLog[@"lastDuration"];
           
        }
        self.lastDuration = last.intValue;
    }];
}

#pragma mark - taskMode

-(void) taskMode_start
{
    self.logger.log(@"taskMode_start");
    
    self.taskMode_backgrounTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [[UIApplication sharedApplication] endBackgroundTask:self.taskMode_backgrounTaskID];
        self.taskMode_backgrounTaskID = UIBackgroundTaskInvalid;
    }];
        
    self.Timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(taskMode_timesCount) userInfo:nil repeats:YES];
    [self.Timer fire];
    
}

-(void) taskMode_stop
{
    self.logger.log(@"taskMode_stop");
    [self.Timer invalidate];
    [[UIApplication sharedApplication] endBackgroundTask:self.taskMode_backgrounTaskID];
    
}

- (void)taskMode_timesCount {
    NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval diff = timestamp - self.startTimestamp;
    self.duration = (NSInteger) diff;
    
    self.times ++;
    self.logger.log(@"taskMode_timesCount times:%ld  duration:%ld",  self.times, self.duration);
//    self.log(@"backgroundTimeRemaining%lf", [UIApplication sharedApplication].backgroundTimeRemaining);
   
    if ([UIApplication sharedApplication].backgroundTimeRemaining < 3.0) {//如果剩余时间小于30秒
        self.logger.log(@"taskMode_timesCount restart");
        [[UIApplication sharedApplication] endBackgroundTask:self.taskMode_backgrounTaskID];
        self.taskMode_backgrounTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
            [[UIApplication sharedApplication] endBackgroundTask:self.taskMode_backgrounTaskID];
            self.taskMode_backgrounTaskID = UIBackgroundTaskInvalid;
        }];
    }
    
}

#pragma mark - locationMode
-(void) locationMode_requestAuthorizaton
{
    
    if (self.locationManager.authorizationStatus == kCLAuthorizationStatusNotDetermined) {
        self.logger.log(@"locationMode_start 请求定位权限");
        
        [self.locationManager requestAlwaysAuthorization];
    }
}
-(void) locationMode_start
{
    self.logger.log(@"locationMode_start");
    
    [self.locationManager startUpdatingLocation];
        
    self.Timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(locationMode_timesCount) userInfo:nil repeats:YES];
    [self.Timer fire];
        
    


}


-(void) locationMode_stop
{
    self.logger.log(@"locationMode_stop");
    [self.Timer invalidate];
    [self.locationManager stopUpdatingHeading];
    
}

- (void)locationMode_timesCount {
    NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval diff = timestamp - self.startTimestamp;
    self.duration = (NSInteger) diff;
    
    self.times ++;
    self.logger.log(@"locationMode_timesCount times:%ld  duration:%ld",  self.times, self.duration);
   
   
    
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    // 处理位置更新
    self.logger.log(@"位置更新 %@", locations);
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    
    self.logger.log(@"定位失败 %@", error);

}
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager {
    
    self.logger.log(@"权限更新 %ld", manager.authorizationStatus);
    
    if (self.locationManager.authorizationStatus == kCLAuthorizationStatusAuthorizedAlways
        || self.locationManager.authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse) {
        
    }
    
}



#pragma mark - audioMode

-(void) audioMode_start
{
    self.logger.log(@"audioMode_start");
    
    NSError *error;
    // 设置音频会话
      [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
                                      withOptions:AVAudioSessionCategoryOptionMixWithOthers
                                            error:&error];
//    if (error) {
//        self.logger.log(@"设置音频类别失败: %@", error);
//           return;
//       }
//    [[AVAudioSession sharedInstance] setActive:YES error:nil];
//    // 激活音频会话
//       [session setActive:YES error:&error];
//       if (error) {
//           NSLog(@"激活音频会话失败: %@", error);
//       }
//    
    
    [self.audioPlayer play];
    
    self.Timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(audioMode_timesCount) userInfo:nil repeats:YES];
    [self.Timer fire];
        
    


}


-(void) audioMode_stop
{
    self.logger.log(@"audioMode_stop");
    [self.Timer invalidate];
    [self.audioPlayer stop];
    
}

- (void)audioMode_timesCount {
    NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval diff = timestamp - self.startTimestamp;
    self.duration = (NSInteger) diff;
    
    self.times ++;
    self.logger.log(@"audioMode_timesCount times:%ld  duration:%ld",  self.times, self.duration);
   
   
    
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    self.logger.log(@"音频 FinishPlaying: %ld", flag);
}

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error {
    self.logger.log(@"音频解码错误: %@", error);
}



@end
